package com.dizner.androiduploadlibrary;

import android.Manifest;
import android.app.Dialog;
import android.app.Service;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.dizner.androiduploadlibrary.javabean.ApplicationUpdateInfoBean;
import com.dizner.androiduploadlibrary.service.UpGradeService;

import java.io.File;
import java.util.Locale;

/**
 * 基于Activity实现的更新界面
 */
public final class InstallApplicationTestActivity extends AppCompatActivity {

    private static final int OTHER_PERMISSION_REQUEST_CODE = 10097;
    private static final int INSTALL_PERMISSION_REQUEST_CODE = 10098;
    public static final String SP_NAME = "downLoadLog";
    private String apkPath;
    private String apkStorePath;//apk存储目录
    @LayoutRes
    private int dialogViewResId;//自定义布局
    private ApplicationUpdateInfoBean updateInfoBean;

    private SharedPreferences sp;
    private String actionType = "upgrade";//install,upgrade
    private static final String TAG = "Upgrade";
    private Dialog mdialog;
    private FrameLayout dialogRootLayout;

    private UpGradeListener upGradeListener;
    private TextView confirmBtn;
    private TextView cancelBtn;

    private int versionCode;

    private UpGradeService upGradeService;
    private ServiceConnection serviceConnection;


    private UpGradeService.UpGradeServerStatusListener downLoadListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initArg();
        start();
        serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                UpGradeService.DownLoadBinder binder = (UpGradeService.DownLoadBinder) service;
                upGradeService = binder.getService();
                upGradeService.setListener(downLoadListener);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                Toast.makeText(InstallApplicationTestActivity.this, "更新服务停止", Toast.LENGTH_SHORT).show();
                finish();
            }
        };
        bindService(new Intent(InstallApplicationTestActivity.this, UpGradeService.class), serviceConnection, Service.BIND_AUTO_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        Window window = getWindow();
        WindowManager.LayoutParams windowParams = window.getAttributes();
        windowParams.alpha = 1f;//1.０全透明．０不透明．
        window.setAttributes(windowParams);

        downLoadListener = new UpGradeService.UpGradeServerStatusListener() {
            @Override
            public void onDownLoadReady(float totalSize) {
                System.out.println("totalSize:" + totalSize);
                Log.i(TAG, "onReady");
            }

            @Override
            public void onDownLoadStart(float totalSize) {
                Log.i(TAG, "onStart:totalSize:" + totalSize);
            }

            @Override
            public void onDownLoadCancel() {
                Log.i(TAG, "onCancel");
            }

            @Override
            public void onDownLoading(final float progress) {
                Log.i(TAG, "onDownLoading:progress:" + progress);
                if (upGradeListener != null) {
                    upGradeListener.onDownLoading(progress);
                }
                if (confirmBtn != null) {
                    confirmBtn.post(new Runnable() {
                        @Override
                        public void run() {
                            if (cancelBtn != null) {
                                cancelBtn.setVisibility(View.GONE);
                            }
                            confirmBtn.setEnabled(false);
                            confirmBtn.setText(String.format(Locale.getDefault(), "%.1f%%", progress));
                        }
                    });
                }
            }

            @Override
            public void onDownLoadError() {

            }

            @Override
            public void onDownLoadFinished(String filePath) {
                Log.i(TAG, "onFinished:filePath:" + filePath);
                sp.edit().putString("lastDownloadPath", filePath).apply();
//                lastDownloadPath = filePath;
                if (upGradeListener != null) {
                    upGradeListener.onDownLoadFinished();
                }
                if (confirmBtn != null) {
                    confirmBtn.post(new Runnable() {
                        @Override
                        public void run() {
                            confirmBtn.setEnabled(true);
                            confirmBtn.setText("安装");
                            if (!updateInfoBean.isMandatory()) {
                                if (cancelBtn != null) {
                                    cancelBtn.setVisibility(View.VISIBLE);
                                }
                            }
                        }
                    });
                }

                checkAndInstall();
            }
        };

    }


    private void start() {
        if (TextUtils.isEmpty(actionType)) {
            Toast.makeText(this, "更新类型错误", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        switch (actionType) {
            case "install":
                checkPermissionAndInstallApk();
                break;
            case "upgrade":
                if (dialogViewResId > 0) {
                    showCustomUpdateInfoDialog();
                } else {
                    showDefaultUpdateInfoDialog();
                }
                break;
        }
    }

    private void initArg() {
        apkPath = getIntent().getStringExtra("apkPath");
        apkStorePath = getIntent().getStringExtra("apkStorePath");
        dialogViewResId = getIntent().getIntExtra("dialogViewResId", 0);
//        fileProviderName = getIntent().getStringExtra("fileProviderName");
        actionType = getIntent().getStringExtra("actionType");
        updateInfoBean = (ApplicationUpdateInfoBean) getIntent().getSerializableExtra("updateInfoBean");

        try {
            versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void onResume() {
        super.onResume();

    }


    public void setUpGradeListener(UpGradeListener upGradeListener) {
        this.upGradeListener = upGradeListener;
    }

    public void showDefaultUpdateInfoDialog() {

        if (updateInfoBean == null) {
            finish();
            return;
        }

        if (updateInfoBean.getNewVersionCode() <= versionCode) {
            finish();
            return;
        }

        View dialogRootView = LayoutInflater.from(this).inflate(R.layout.layout_dialog, null);


        try {
            dialogRootLayout = dialogRootView.findViewById(R.id.fl_dialog_root_view);
            View dialogView = LayoutInflater.from(this).inflate(R.layout.upgrade_dialog_default, dialogRootLayout, false);
            if (dialogView != null) {
                dialogView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                dialogRootLayout.removeAllViews();
                dialogRootLayout.addView(dialogView);
            }
        } catch (Exception e) {
            e.printStackTrace();
            showDefaultUpdateInfoDialog();
        }


        confirmBtn = dialogRootView.findViewWithTag("upgrade_confirm_btn");
        cancelBtn = dialogRootView.findViewWithTag("upgrade_cancel_btn");
        ImageView icon = dialogRootView.findViewWithTag("upgrade_icon");
        TextView title = dialogRootView.findViewWithTag("upgrade_title");
        TextView upgradeInfo = dialogRootView.findViewWithTag("upgrade_info");


        mdialog = new Dialog(this);
        mdialog.setContentView(dialogRootView);
        UpTestGradeManager.Builder.contentView = dialogRootLayout;
        if (icon != null) {
            try {
                icon.setImageResource(updateInfoBean.getIcon());
                icon.setVisibility(View.VISIBLE);
            } catch (Exception e) {
                e.printStackTrace();
                icon.setVisibility(View.GONE);
            }
        }

        if (!updateInfoBean.isMandatory() && (cancelBtn != null)) {//非强制更新显示取消按钮
            cancelBtn.setVisibility(View.VISIBLE);
            cancelBtn.setText("取消");
            cancelBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mdialog.cancel();
                    finish();
                    if (upGradeListener != null) {
                        upGradeListener.onCancelBtnClick();
                    }
                }
            });
        } else {
            if (cancelBtn != null) {
                cancelBtn.setVisibility(View.GONE);
            }
        }

        String okBtnStr = "更新";
        if (hasApkPackage()) {
            okBtnStr = "安装";
        }
        if (confirmBtn != null) {
            confirmBtn.setText(okBtnStr);
            confirmBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (upGradeListener != null) {
                        upGradeListener.onConfirmBtnClick();
                    }
                    if (hasApkPackage()) {
                        checkPermissionAndInstallApk();
                    } else {
                        if (TextUtils.isEmpty(apkStorePath)) {
                            throw new IllegalArgumentException("apkStorePath is empty");
                        }
                        FileUtils.delAllFile(apkStorePath);
                        // TODO: 2018/9/27 下载
                        upGradeService.startDownLoad();
                        if (upGradeListener != null) {
                            upGradeListener.onStartDownLoad();
                        }

                        if (!updateInfoBean.isMandatory() && mdialog != null) {
                            mdialog.cancel();
                            finish();
                        }
                    }

                }
            });
        }
        if (title != null)
            title.setText(updateInfoBean.getTitle());
        if (upgradeInfo != null)
            upgradeInfo.setText(updateInfoBean.getUpdateInfoString());
        if (confirmBtn == null || cancelBtn == null || title == null) {
            showDefaultUpdateInfoDialog();
        }
        mdialog.setCanceledOnTouchOutside(false);
        mdialog.setCancelable(false);
        mdialog.show();

        Window dialogWindow = mdialog.getWindow();
        if (dialogWindow != null) {
            dialogWindow.setBackgroundDrawableResource(R.drawable.dialog_trans);
            dialogWindow.setGravity(Gravity.CENTER);
        }
    }


    /**
     * 自定义视图
     */
    public void showCustomUpdateInfoDialog() {


        if (updateInfoBean == null) {
            finish();
            return;
        }

        if (updateInfoBean.getNewVersionCode() <= versionCode) {
            finish();
            return;
        }

        View dialogRootView = LayoutInflater.from(this).inflate(R.layout.layout_dialog, null);


        try {
            dialogRootLayout = dialogRootView.findViewById(R.id.fl_dialog_root_view);
            View dialogView = LayoutInflater.from(this).inflate(dialogViewResId, dialogRootLayout, false);
            if (dialogView != null) {
                dialogView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                dialogRootLayout.removeAllViews();
                dialogRootLayout.addView(dialogView);
            }
        } catch (Exception e) {
            e.printStackTrace();
            showDefaultUpdateInfoDialog();
        }

        confirmBtn = dialogRootView.findViewWithTag("upgrade_confirm_btn");
        cancelBtn = dialogRootView.findViewWithTag("upgrade_cancel_btn");
        ImageView icon = dialogRootView.findViewWithTag("upgrade_icon");
        TextView title = dialogRootView.findViewWithTag("upgrade_title");
        TextView upgradeInfo = dialogRootView.findViewWithTag("upgrade_info");


        mdialog = new Dialog(this);
        mdialog.setContentView(dialogRootView);

        if (icon != null) {
            try {
                icon.setImageResource(updateInfoBean.getIcon());
                icon.setVisibility(View.VISIBLE);
            } catch (Exception e) {
                e.printStackTrace();
                icon.setVisibility(View.GONE);
            }
        }

        if (!updateInfoBean.isMandatory() && (cancelBtn != null)) {//非强制更新显示取消按钮
            cancelBtn.setVisibility(View.VISIBLE);
            cancelBtn.setText("取消");
            cancelBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mdialog.cancel();
                    finish();
                    if (upGradeListener != null) {
                        upGradeListener.onCancelBtnClick();
                    }
                }
            });
        } else {
            if (cancelBtn != null) {
                cancelBtn.setVisibility(View.GONE);
            }
        }

        String okBtnStr = "更新";
        if (hasApkPackage()) {
            okBtnStr = "安装";
        }
        if (confirmBtn != null) {
            confirmBtn.setText(okBtnStr);
            confirmBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (upGradeListener != null) {
                        upGradeListener.onConfirmBtnClick();
                    }
                    if (hasApkPackage()) {
                        checkPermissionAndInstallApk();
                    } else {
                        if (TextUtils.isEmpty(apkStorePath)) {
                            throw new IllegalArgumentException("apkStorePath is empty");
                        }
                        FileUtils.delAllFile(apkStorePath);

                        // TODO: 2018/9/27 下载
                        upGradeService.startDownLoad();

                        if (upGradeListener != null) {
                            upGradeListener.onStartDownLoad();
                        }
                        if (!updateInfoBean.isMandatory() && mdialog != null) {
                            mdialog.cancel();
                            finish();
                        }
                    }


                }
            });
        }
        if (title != null)
            title.setText(updateInfoBean.getTitle());
        if (upgradeInfo != null)
            upgradeInfo.setText(updateInfoBean.getUpdateInfoString());
        if (confirmBtn == null || cancelBtn == null || title == null) {
            showDefaultUpdateInfoDialog();
        }
        mdialog.setCanceledOnTouchOutside(false);
        mdialog.setCancelable(false);
        mdialog.show();

        Window dialogWindow = mdialog.getWindow();
        if (dialogWindow != null) {
            dialogWindow.setBackgroundDrawableResource(R.drawable.dialog_trans);
            dialogWindow.setGravity(Gravity.CENTER);
        }
    }

    public void checkAndInstall() {
        if (hasApkPackage()) {
            checkPermissionAndInstallApk();
        } else {
            Toast.makeText(getApplicationContext(), "读取安装包失败，请重试", Toast.LENGTH_SHORT).show();
            finish();
        }
    }


    private boolean hasApkPackage() {
        sp = getSharedPreferences(SP_NAME, MODE_PRIVATE);

        String lastDownloadPath = sp.getString("lastDownloadPath", "");
        Log.i(TAG, "checkApkFile_step1:" + lastDownloadPath);
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {

                if (!TextUtils.isEmpty(lastDownloadPath)) {

                    File file = new File(lastDownloadPath);

                    Log.i(TAG, "checkApkFile_step2: lastDownloadPath has");
                    if (file != null && file.canRead()) {

                        String fileMD5 = FileUtils.getFileMD5ToString(file);
                        Log.i(TAG, "checkApkFile_step3:" + fileMD5);

                        PackageInfo packageInfo = getPackageManager().getPackageArchiveInfo(file.getPath(), PackageManager.GET_ACTIVITIES);
                        if (packageInfo != null) {
                            Log.i(TAG, "checkApkFile_step4:" + packageInfo.toString());
                        }
//                    //校验本地安装包的合法性
//                    if (packageInfo != null && packageInfo.versionCode == updateInfoBean.getNewVersionCode()
//                            && TextUtils.equals(updateInfoBean.getNewVersionName(), packageInfo.versionName)
//                            && TextUtils.equals(fileMD5, updateInfoBean.getNewApkFileMd5())) {
//                        apkPath = file.getPath();
//                        return true;
//                    }
                        //校验本地安装包的合法性
                        apkPath = file.getPath();
                        return true;
//                        if (packageInfo != null && packageInfo.versionCode == updateInfoBean.getNewVersionCode()) {
//                            if (!TextUtils.isEmpty(updateInfoBean.getNewApkFileMd5()) && !TextUtils.equals(fileMD5, updateInfoBean.getNewApkFileMd5())) {
//                                Log.i(TAG, "checkApkFile_step5: md5 failed");
//                                return false;
//                            }
//                            apkPath = file.getPath();
//                            return true;
//                        } else {
//                            Log.i(TAG, "checkApkFile_step5: packageInfo failed-versionCode");
//                        }

                    } else {
                        Log.i(TAG, "checkApkFile_step3: file read failed");
                        return false;
                    }


                }
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, OTHER_PERMISSION_REQUEST_CODE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return false;
    }

    /**
     * 描述：打开并安装文件.
     */
    public void checkPermissionAndInstallApk() {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            boolean haveInstallPermission = getPackageManager().canRequestPackageInstalls();
            if (haveInstallPermission) {
                install();
            } else {
                AlertDialog dialog = new AlertDialog.Builder(this).setTitle(R.string.app_name).setMessage("更新应用需要获得相关权限，是否去授权？").setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(getApplicationContext(), "取消授权", Toast.LENGTH_SHORT).show();
                        dialog.cancel();
                        if (upGradeListener != null) {
                            upGradeListener.onError();
                        }
                        finish();
                    }
                }).setPositiveButton("授权", new DialogInterface.OnClickListener() {
                    @RequiresApi(api = Build.VERSION_CODES.O)
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startInstallPermissionSettingActivity();
                    }
                }).create();
                dialog.setCanceledOnTouchOutside(false);
                dialog.setCancelable(false);
                dialog.show();

            }
        } else {
            install();
        }


    }


    private void install() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            Uri uri = null;
            if (TextUtils.isEmpty(apkPath)) {
                Toast.makeText(InstallApplicationTestActivity.this, "读取安装包失败" + apkPath, Toast.LENGTH_SHORT).show();
                return;
            }
            File file = new File(apkPath);
            if (!file.canRead()) {
                Toast.makeText(InstallApplicationTestActivity.this, "读取安装包失败" + apkPath, Toast.LENGTH_SHORT).show();
                if (upGradeListener != null) {
                    upGradeListener.onError();
                }
                finish();
                return;
            }
            Intent intent = new Intent(Intent.ACTION_VIEW);
            // 由于没有在Activity环境下启动Activity,设置下面的标签
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (Build.VERSION.SDK_INT >= 24) {
                uri = FileProvider.getUriForFile(InstallApplicationTestActivity.this, UpdateFileProvider.getFileProviderName(), file);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            } else {
                uri = Uri.fromFile(file);
            }

            intent.setDataAndType(uri,
                    "application/vnd.android.package-archive");
            startActivity(intent);
            if (upGradeListener != null) {
                upGradeListener.onStartInstall();
            }
//            if (!updateInfoBean.isMandatory()) {
//                if (mdialog != null) {
//                    mdialog.dismiss();
//                    finish();
//                }
//            }

        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, OTHER_PERMISSION_REQUEST_CODE);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity() {
        Uri packageURI = Uri.parse("package:" + getPackageName());
        //注意这个是8.0新API
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
        startActivityForResult(intent, INSTALL_PERMISSION_REQUEST_CODE);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == INSTALL_PERMISSION_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                checkPermissionAndInstallApk();
            } else {
                Toast.makeText(getApplicationContext(), "授权失败", Toast.LENGTH_SHORT).show();
                if (upGradeListener != null) {
                    upGradeListener.onError();
                }
                finish();
            }
        } else {
            finish();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case OTHER_PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    install();
                } else {
                    //用户不同意，向用户展示该权限作用
                    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                        new AlertDialog.Builder(this)
                                .setMessage(R.string.storage_permissions_remind)
                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        ActivityCompat.requestPermissions(InstallApplicationTestActivity.this,
                                                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                                OTHER_PERMISSION_REQUEST_CODE);
                                    }
                                })
                                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        Toast.makeText(getApplicationContext(), "授权失败", Toast.LENGTH_SHORT).show();
                                        if (upGradeListener != null) {
                                            upGradeListener.onError();
                                        }
                                        finish();
                                    }
                                })
                                .create()
                                .show();
                    }

                }
            default:
                finish();
                break;
        }
    }

    public Dialog getDialog() {

        return mdialog;
    }


    public View getContentView() {
        return dialogRootLayout;
    }


    @Override
    protected void onDestroy() {
        if (upGradeService != null) {
            upGradeService.stopService(this);
        }
        if (serviceConnection != null) {
            unbindService(serviceConnection);
        }

        super.onDestroy();
    }

    public interface UpGradeListener {
        void onConfirmBtnClick();

        void onCancelBtnClick();

        void onStartInstall();

        void onError();

        void onStartDownLoad();

        void onDownLoading(float progress);

        void onDownLoadFinished();
    }
}
